#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
/*
 * @lc app=leetcode.cn id=239 lang=cpp
 *
 * [239] 滑动窗口最大值
 */

// @lc code=start
class Solution {
public:
    // 优先级队列的解法
    // vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    //     vector<int> res; priority_queue<pair<int, int>> q;
    //     for (int i = 0; i < k; i++) q.emplace(nums[i], i);
    //     res.push_back(q.top().first);
    //     for (int i = k; i < nums.size(); i++) {
    //         q.emplace(nums[i], i);
    //         while (q.top().second < i - k + 1) q.pop();
    //         res.push_back(q.top().first);
    //     }
    //     return res;
    // }

    // 双向队列
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res; deque<int> q;
        for (int i = 0; i < k; i++) {
            while (!q.empty() && nums[i] >= nums[q.back()]) q.pop_back();
            q.push_back(i);
        }
        res.push_back(nums[q.front()]);
        for (int i = k; i < nums.size(); i++) {
            while (!q.empty() && nums[i] >= nums[q.back()]) q.pop_back();
            q.push_back(i);
            while (q.front() < i - k + 1) q.pop_front();
            res.push_back(nums[q.front()]);
        }
        return res;
    }
};
// @lc code=end

